home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1998
/
MacHack 1998.toast
/
The Hacks!
/
mhTV ƒ
/
TVSource
/
SourceThatMatters
/
Import
/
TVImportComponent.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-20
|
14KB
|
467 lines
#include "Maynard.h"
#include "ComponentHelp.h"
#include <Files.h>
#include <FixMath.h>
#include <Resources.h>
#include <ToolUtils.h>
#include <QuickTimeComponents.h>
#include <MediaHandlers.h>
#include "TVImportVersion.h"
///=============================================================================
#if STAND_ALONE
#define ImportTVDispatchSelector main
#else
Component RegisterTVImport(void);
#endif //STAND_ALONE
pascal ComponentResult ImportTVDispatchSelector(
ComponentParameters *paramsPtr, Handle thiss);
///=============================================================================
#define kMovieTimeScale 600
#define kMPEGTrackTimeScale 600
struct TVImportRecord{
MovieImportComponent self;
};
typedef struct TVImportRecord TVImportRecord;
///-----------------------------------------------------------------------------
#define STATIC static
#define COMPONENT
STATIC COMPONENT ComponentResult TVImportOpen(
TVImportRecord* thiss, MovieImportComponent self);
STATIC COMPONENT ComponentResult TVImportClose(
TVImportRecord* thiss, MovieImportComponent self);
STATIC COMPONENT ComponentResult TVImportCanDo(
TVImportRecord* thiss, short selector);
STATIC COMPONENT ComponentResult TVImportVersion(
TVImportRecord* thiss);
STATIC COMPONENT TVImportGetMIMETypeList(
TVImportRecord* thiss, QTAtomContainer* containerPtr);
STATIC COMPONENT ComponentResult ImportTVImportFile(
TVImportRecord* thiss, FSSpec const* fsSpecPtr,
Movie movie, Track targetTrack, Track* usedTrackPtr,
TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr);
STATIC COMPONENT ComponentResult ImportTVImportDataRef(
TVImportRecord* thiss, Handle dataRef, OSType dataRefType,
Movie movie, Track targetTrack, Track* usedTrackPtr,
TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr);
STATIC COMPONENT ComponentResult TVImportValidate(
TVImportRecord* thiss, FSSpec const* fsSpecPtr, Handle dataH,
Boolean* fValidPtr);
///-----------------------------------------------------------------------------
static ComponentResult SG_DoTheImport(
TVImportRecord* thiss,
Movie theMovie, Track targetTrack, Track* usedTrackPtr,
TimeValue atTime, TimeValue* addedTimePtr,
long inFlags, long* outFlagsPtr);
///*****************************************************************************
#if GENERATINGPOWERPC
//Note that while this struct may appear to be a static variable, it
// actually MUST be exported because it is the entry point used by the
// component manager when it connects to this code fragment.
struct RoutineDescriptor ImportTVSelectorDispatcher
=BUILD_ROUTINE_DESCRIPTOR(
kPascalStackBased
|RESULT_SIZE(kFourByteCode)
|STACK_ROUTINE_PARAMETER(1,kFourByteCode)
|STACK_ROUTINE_PARAMETER(2,kFourByteCode),
ImportTVDispatchSelector);
#endif //GENERATINGPOWERPC
///-----------------------------------------------------------------------------
#if !STAND_ALONE
Component RegisterTVImport(void)
{
#if GENERATINGPOWERPC
#define componentEntryPoint &ImportTVSelectorDispatcher
#define registrationFlags 0x200|registerComponentGlobal
//Note the 0x200 tells RegisterComponent() we are PPC native.
#else
#define componentEntryPoint TVImportDispatchSelector
#define registrationFlags registerComponentGlobal
#endif
#define kFileType \
canMovieImportFiles|canMovieImportInPlace
ComponentDescription cd;
Component registeredComponent;
//Remove any older versions of this component.
cd.componentType =MovieImportType;
cd.componentManufacturer=0;
cd.componentFlags =0;
cd.componentFlagsMask =0;
/*
opens file type mhTV
is initially an empty file
-- so this sets (makes up)
height/width
duration (max)
movie controller
(what else)
-- so can kill all the MPEG and mpyc/WIRED components
then add so pops up a dialog for the VDIG and stores results
plus try strange matrix/effects
*/
cd.componentSubType =FOUR_CHAR_CODE('mhTV');
registeredComponent=NULL;
do{
registeredComponent=FindNextComponent(registeredComponent, &cd);
UnregisterComponent(registeredComponent);
}while(registeredComponent);
///.............................................................................
//Now register this component to eat muxed MPEG.
cd.componentType =MovieImportType;
cd.componentManufacturer=FOUR_CHAR_CODE('mhTV');
cd.componentFlagsMask =0;
cd.componentSubType =FOUR_CHAR_CODE('mhTV');
cd.componentFlags =kFileType|canMovieImportValidateFile;
cd.componentFlagsMask =0;
registeredComponent=RegisterComponent(&cd,
componentEntryPoint, registrationFlags, 0, 0, 0);
SetDefaultComponent(registeredComponent,
defaultComponentAnyFlagsAnyManufacturer);
return registeredComponent;
}
#endif //STAND_ALONE
///-----------------------------------------------------------------------------
pascal ComponentResult ImportTVDispatchSelector(
ComponentParameters* paramsPtr, Handle thiss)
{
#define cmpGlobalParm REINTERPRET_CAST(TVImportRecord*, thiss)
ComponentResult error=badComponentSelector;
switch(paramsPtr->what){
///.........................................................................
//Component manager selectors.
case kComponentOpenSelect:
error=TVImportOpen(
CMP1(MovieImportComponent) );
break;
case kComponentCloseSelect:
error=TVImportClose(
CMP1(MovieImportComponent) );
break;
case kComponentCanDoSelect:
error=TVImportCanDo(
CMP1(short) );
break;
case kComponentVersionSelect:
error=TVImportVersion(
CMP0() );
break;
///.........................................................................
//Import component selectors.
case kMovieImportValidateSelect:
error=TVImportValidate(
CMP3(FSSpec const*, Handle, Boolean*) );
break;
case kMovieImportFileSelect:
error=ImportTVImportFile(
CMP8(FSSpec const*, Movie, Track, Track*,
TimeValue, TimeValue*, long, long*) );
break;
case kMovieImportDataRefSelect:
error=ImportTVImportDataRef(
CMP9(Handle, OSType, Movie, Track, Track*,
TimeValue, TimeValue*, long, long*) );
break;
}
return error;
}
///=============================================================================
STATIC COMPONENT ComponentResult TVImportVersion(TVImportRecord* thiss)
{
#pragma unused (thiss)
return kTVImportVersion;
}
///-----------------------------------------------------------------------------
STATIC COMPONENT ComponentResult TVImportCanDo(TVImportRecord* thiss,
short functionNumber)
{
#pragma unused (thiss)
switch(functionNumber){
case kComponentOpenSelect:
case kComponentCloseSelect:
case kComponentCanDoSelect:
case kComponentVersionSelect:
case kMovieImportGetMIMETypeListSelect:
case kMovieImportValidateSelect:
case kMovieImportFileSelect:
case kMovieImportDataRefSelect:
return TRUE;
default:
return FALSE;
}
}
///=============================================================================
STATIC COMPONENT ComponentResult TVImportOpen(TVImportRecord* dummy,
MovieImportComponent self)
{
#pragma unused(dummy)
//This component does not use any class meta-data hence we are spared the
// hassle of handling global memory allocation from the system heap.
OSErr error=noErr;
TVImportRecord* thiss;
ASSERT(self!=NULL);
thiss=STATIC_CAST(TVImportRecord*,
NewPtrClear( sizeof(TVImportRecord)) );
if(thiss==NULL){
error=MemError();
FLAG_ERROR(error);
goto cleanup;
}
SetComponentInstanceStorage(self, STATIC_CAST(Handle, thiss) );
thiss->self=self;
goto done;
cleanup:
//No cleanup to do.
done:
return error;
}
///-----------------------------------------------------------------------------
STATIC COMPONENT ComponentResult TVImportClose(TVImportRecord* thiss,
MovieImportComponent self)
{
#pragma unused(self)
DisposePtr( STATIC_CAST(Ptr, thiss) );
return noErr;
}
///=============================================================================
STATIC COMPONENT ComponentResult ImportTVImportFile(TVImportRecord* thiss,
FSSpec const* fsSpecPtr,
Movie movie, Track targetTrack, Track* usedTrackPtr,
TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr)
{
OSErr error;
AliasHandle fileAliasH=NULL;
ASSERT(fsSpecPtr!=NULL);
error=NewAliasMinimal(fsSpecPtr, &fileAliasH);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
error=ImportTVImportDataRef(thiss,
STATIC_CAST(Handle, fileAliasH), rAliasType,
movie, targetTrack, usedTrackPtr,
atTime, addedTimePtr, inFlags, outFlagsPtr);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
goto done;
cleanup:
//No cleanup necessary.
done:
DisposeHandle( STATIC_CAST(Handle, fileAliasH) );
return error;
}
///-----------------------------------------------------------------------------
STATIC COMPONENT ComponentResult ImportTVImportDataRef(TVImportRecord* thiss,
Handle dataRef, OSType dataRefType,
Movie movie, Track targetTrack, Track* usedTrackPtr,
TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr)
{
ComponentResult error;
Component dataHandlerClass;
DataHandler dataHandler=NULL;
ASSERT(thiss!=NULL);
ASSERT(dataRef!=NULL);
ASSERT(movie!=NULL);
//A targetTrack of non-NULL is for importing into a specific track rather
// than a movie.
//It's not clear that we'll ever have to support this for mhTV.
if(targetTrack!=NULL){
error=paramErr; FLAG_ERROR(error); goto cleanup;
}
dataHandlerClass=GetDataHandler(dataRef, dataRefType, kDataHCanRead);
if(dataHandlerClass==NULL){
error=cantOpenHandler; FLAG_ERROR(error); goto cleanup;
}
error=OpenAComponent(dataHandlerClass, &dataHandler);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
error=DataHSetDataRef(dataHandler, dataRef );
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
//Make the movie point to the selected file
SetMovieDefaultDataRef(movie, dataRef, dataRefType);
error=SG_DoTheImport(thiss, movie, targetTrack, usedTrackPtr,
atTime, addedTimePtr, inFlags, outFlagsPtr);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
goto done;
cleanup:
//No cleanup necessary.
done:
CloseComponent(dataHandler);
return error;
}
///-----------------------------------------------------------------------------
static ComponentResult SG_DoTheImport(TVImportRecord* thiss,
Movie movie, Track targetTrack, Track* usedTrackPtr,
TimeValue atTime, TimeValue* addedTimePtr, long inFlags, long* outFlagsPtr)
{
#pragma unused (thiss, addedTimePtr, inFlags)
//This is full volume (1.0 in 8.8 format).
const int kSuggestedMovieVolume=0x100;
ComponentResult error;
// ComponentResult mediaHandlerStatus;
long sampleOffset, sampleSize;
OSType mhlrType;
Track mpegTrack=NULL;
Media mpegMedia=NULL;
long suggestedMovieWidth;
long suggestedMovieHeight;
TimeValue mpegTrackDuration=0;
Fixed fxEditRate;
long outFlags;
QTAtomContainer sampleInfoContainer=NULL;
Size sampleInfoContainerSize;
Handle h=NULL;
SampleDescription* sampleDescriptionAlias;
ASSERT(thiss!=NULL);
ASSERT(movie!=NULL);
ASSERT(targetTrack==NULL);
error=QTNewAtomContainer(&sampleInfoContainer);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
sampleInfoContainerSize=GetHandleSize(sampleInfoContainer);
h=NewHandleClear(
sizeof(SampleDescription) ); //(+sampleInfoContainerSize );
if(h==NULL) {error=MemError(); FLAG_ERROR(error); goto cleanup;}
sampleDescriptionAlias=STATIC_CAST(SampleDescription*, *h);
sampleDescriptionAlias->descSize
=sizeof(SampleDescription);// +sampleInfoContainerSize;
sampleDescriptionAlias->dataFormat=0;
// =sgEMPEGToSampleDescriptionDataFormat[mpegType];
sampleDescriptionAlias->resvd1 =0;
sampleDescriptionAlias->resvd2 =0;
sampleDescriptionAlias->dataRefIndex=0;
//BlockMoveData(*sampleInfoContainer, (*h)+sizeof(SampleDescription),
// sampleInfoContainerSize );
///.............................................................................
SetMovieTimeScale(movie, kMovieTimeScale);
suggestedMovieWidth =320;
suggestedMovieHeight=240;
mpegTrack=NewMovieTrack(movie,
suggestedMovieWidth<<16, suggestedMovieHeight<<16, kSuggestedMovieVolume);
error=GetMoviesError();
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
mhlrType='mhTV';
mpegMedia=NewTrackMedia(mpegTrack, mhlrType,
kMPEGTrackTimeScale, NULL, 0);
error=GetMoviesError();
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
mpegTrackDuration=0x7FFFFFFF;
sampleOffset=0;
sampleSize =1;
error=AddMediaSampleReference(mpegMedia,
sampleOffset, sampleSize, mpegTrackDuration,
STATIC_CAST(SampleDescriptionHandle, h), 1, 0, NULL);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
fxEditRate=kfxOne;
error=InsertMediaIntoTrack(mpegTrack, atTime, 0,
mpegTrackDuration, fxEditRate);
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
SetTrackEnabled(mpegTrack, TRUE);
error=GetMoviesError();
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
{
RGBColor rgb;
rgb.red =0x0FFF;
rgb.green=0x0000;
rgb.blue =0x0000;
error=MediaSetGraphicsMode( GetMediaHandler(mpegMedia),
ditherCopy, NULL );
//( addMax, &rgb );
if(error!=noErr) {FLAG_ERROR(error); goto cleanup;}
}
goto done;
cleanup:
DisposeMovieTrack(mpegTrack);
mpegTrack=NULL;
done:
QTDisposeAtomContainer(sampleInfoContainer);
DisposeHandle(h);
if(usedTrackPtr) *usedTrackPtr=mpegTrack;
if(addedTimePtr) *addedTimePtr=mpegTrackDuration;
outFlags=0;
if(outFlagsPtr) *outFlagsPtr=outFlags;
return error;
}
///=============================================================================
STATIC COMPONENT ComponentResult TVImportValidate(TVImportRecord* thiss,
FSSpec const* fsSpecPtr, Handle dataH, Boolean* fValidPtr)
{
#pragma unused (thiss, fsSpecPtr, dataH)
ASSERT(fValidPtr!=NULL);
*fValidPtr=TRUE;
return noErr;
}
///=============================================================================